package com.zhanglijie.improve.aqs.mix.readwrite.sysdemo;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @author zhanglijie
 * @version 1.0
 * @since 1.1.0 2022/10/23 0023 19:49
 */
public class ReadWriteTestDemo3 {
    //1.如果t1线程拿到写锁之后 可以继续拿读锁，锁降级后 t2线程可以读吗？  不可以 即使锁降级了但是写锁没释放 别的线程就无法进行读操作
    //2.如果t1线程只拿到读锁 进行读时候 t2线程可以拿读锁一起读
    //3.如果t1线程只拿到写锁然后继续拿读锁（锁降级了） 然后在读阻塞前释放写锁  t2线程可以拿读锁一起读
    //4,演示如果t1线程只拿到写锁然后继续拿读锁（锁降级了），此时t1只有读锁  t2是不能获得写锁的
    static ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
    static Lock readLock = reentrantReadWriteLock.readLock();
    static Lock writeLock = reentrantReadWriteLock.writeLock();

    public static void main(String[] args) throws InterruptedException {
       // new Thread(()->{ //演示t1线程拿到写锁之后 可以继续拿读锁，锁降级后 t2线程可以读吗？  不可以 即使锁降级了但是写锁没释放 别的线程就无法进行读操作
       //     try {
       //          writeLock.lock();
       //         System.out.println(Thread.currentThread().getName()+"获得写锁");
       //         readLock.lock();
       //         System.out.println(Thread.currentThread().getName()+"继续获得了读锁");
       //         Thread.sleep(5000);
       //         System.out.println(Thread.currentThread().getName()+"读进行中");
       //     }catch (Exception e){
       //         e.printStackTrace();
       //     }finally {
       //          writeLock.unlock();
       //         System.out.println("释放了写锁");
       //         readLock.unlock();
       //         System.out.println("释放读锁");
       //     }
       // },"t1").start();
       // Thread.sleep(300);
       //
       // new Thread(()->{
       //     try{
       //         readLock.lock();
       //         System.out.println(Thread.currentThread().getName()+"执行读操作了");
       //     }finally {
       //         readLock.lock();
       //     }
       // },"t2").start();





        // new Thread(()->{ //演示如果t1线程只拿到读锁 进行读时候 t2线程可以拿读锁一起读
        //     try {
        //         readLock.lock();
        //         System.out.println(Thread.currentThread().getName()+"继续获得了读锁");
        //         Thread.sleep(5000);
        //         System.out.println(Thread.currentThread().getName()+"读进行中");
        //     }catch (Exception e){
        //         e.printStackTrace();
        //     }finally {
        //         System.out.println("释放了写锁");
        //         readLock.unlock();
        //         System.out.println("释放读锁");
        //     }
        // },"t1").start();
        // Thread.sleep(300);
        //
        // new Thread(()->{
        //     try{
        //         readLock.lock();
        //         System.out.println(Thread.currentThread().getName()+"执行读操作了");
        //     }finally {
        //         readLock.lock();
        //     }
        // },"t2").start();



        // new Thread(()->{ //演示如果t1线程只拿到写锁然后继续拿读锁（锁降级了） 然后在读阻塞前释放写锁  t2线程可以拿读锁一起读
        //     try {
        //         writeLock.lock();
        //         System.out.println(Thread.currentThread().getName()+"获得写锁");
        //         readLock.lock();
        //         System.out.println(Thread.currentThread().getName()+"继续获得了读锁");
        //         writeLock.unlock();
        //         Thread.sleep(5000);
        //         System.out.println(Thread.currentThread().getName()+"读进行中");
        //     }catch (Exception e){
        //         e.printStackTrace();
        //     }finally {
        //         System.out.println("释放了写锁");
        //         readLock.unlock();
        //         System.out.println("释放读锁");
        //     }
        // },"t1").start();
        // Thread.sleep(300);
        //
        // new Thread(()->{
        //     try{
        //         readLock.lock();
        //         System.out.println(Thread.currentThread().getName()+"执行读操作了");
        //     }finally {
        //         readLock.lock();
        //     }
        // },"t2").start();



        new Thread(()->{ //演示如果t1线程只拿到写锁然后继续拿读锁（锁降级了），此时t1只有读锁  t2是不能获得写锁的
            try {
                writeLock.lock();
                System.out.println(Thread.currentThread().getName()+"获得写锁");
                readLock.lock();
                System.out.println(Thread.currentThread().getName()+"继续获得了读锁");
                writeLock.unlock();
                Thread.sleep(5000);
                System.out.println(Thread.currentThread().getName()+"读进行中");
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                System.out.println("释放了写锁");
                readLock.unlock();
                System.out.println("释放读锁");
            }
        },"t1").start();
        Thread.sleep(300);

        new Thread(()->{
            try{
                writeLock.lock();
                System.out.println(Thread.currentThread().getName()+"执行写操作了");
            }finally {
                writeLock.lock();
            }
        },"t2").start();
    }

}
